package com.whisperly.echotalk.starryb.schemas;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.LoudnessEnhancer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.appsflyer.AFInAppEventParameterName;
import com.appsflyer.AFInAppEventType;
import com.appsflyer.AppsFlyerLib;
import com.appsflyer.attribution.AppsFlyerRequestListener;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.nativead.MediaView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdOptions;
import com.google.android.gms.ads.nativead.NativeAdView;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;
import com.google.android.gms.ads.rewarded.ServerSideVerificationOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.hjq.permissions.OnPermission;
import com.hjq.permissions.XXPermissions;
import com.whisperly.echotalk.bllmodel.BaseResponse;
import com.whisperly.echotalk.bllmodel.ChatContentAdapter;
import com.whisperly.echotalk.bllmodel.ChatHistory;
import com.whisperly.echotalk.bllmodel.ChatWithUser;
import com.whisperly.echotalk.bllmodel.CommonResponse;
import com.whisperly.echotalk.bllmodel.ResultBody;
import com.whisperly.echotalk.bllmodel.ReturnedValue;
import com.whisperly.echotalk.bllmodel.SignUp;
import com.whisperly.echotalk.bllmodel.UpdateInfo;
import com.whisperly.echotalk.bllmodel.UserQuery;
import com.whisperly.echotalk.bllmodel.UserWithChat;
import com.whisperly.echotalk.other.Settings;
import com.whisperly.echotalk.starryb.R;
import com.whisperly.echotalk.starryb.netWorkUtils.ApiService;
import com.whisperly.echotalk.starryb.netWorkUtils.BlinkCallback;
import com.whisperly.echotalk.starryb.netWorkUtils.NetworkCallback;
import com.whisperly.echotalk.starryb.netWorkUtils.NetworkUtils;
import com.whisperly.echotalk.starryb.utils.AppsManager;
import com.whisperly.echotalk.starryb.utils.BaseURL;
import com.whisperly.echotalk.starryb.utils.Flash;
import com.whisperly.echotalk.starryb.utils.GlobalData;

import org.checkerframework.checker.units.qual.A;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class AI extends AppCompatActivity implements ChatContentAdapter.OnMessageLongClickListener{
    public ListView listView;
    public EditText et_send_msg;
    public Button btn_send;
    public ChatContentAdapter adapter;
    private Toast currentToast;
    private List<ChatWithUser> chatBeanList = new ArrayList<>();;
    private String[] welcome;
    private String send_Msg;
    private ChatWithUser chatWithUser;
    private int MSG_OK = 1;
    private long exitTime = 0;
    private int position;
    private UserWithChat user = new UserWithChat();
    private View sigup_view;
    private View comparision_view;
    private AlertDialog write;
    private ImageButton signup;
    private static final String PREFS_NAME2 = "MyPrefsFile";
    private static final String PREF_VERSION_CODE_KEY = "version_code";
    private static final String DOESNT_EXIST = "-1";
    private SharedPreferences prefs;
    private RewardedAd mRewardedAd;
    private static final String TAG = "RewardedAd";
    private boolean mUserEarnedReward = false;
    private boolean isSigningUp = false;

    private View navigationBarSpacer;

    @Override
    protected void attachBaseContext(Context newBase) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase);
        String languageCode = prefs.getString("language", "en");
        super.attachBaseContext(updateResources(newBase, languageCode));
    }


    public Context updateResources(Context context, String languageCode) {
        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources res = context.getResources();
        Configuration config = new Configuration(res.getConfiguration());
        config.setLocale(locale);
        LocaleList localeList = new LocaleList(locale);
        LocaleList.setDefault(localeList);
        config.setLocales(localeList);
        context = context.createConfigurationContext(config);
        return context;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置全面屏显示
        setupFullScreenDisplay();

        AppsManager.addActivity(this);
        setContentView(R.layout.aimain);
        prefs = getSharedPreferences(PREFS_NAME2, MODE_PRIVATE);

        // 同步本地签到数据
        syncSignUpData();

        loadRewardedAd();

        Toolbar infoToolbar = findViewById(R.id.toolbar);
        user = GlobalData.getUser();
        setSupportActionBar(infoToolbar);
        ActionBar infoActionBar = getSupportActionBar();
        if (infoActionBar != null) {
            infoActionBar.setDisplayShowTitleEnabled(false); // 不显示默认标题
        }
        TextView toolbarTitle = findViewById(R.id.toolbar_title);
        toolbarTitle.setText(R.string.toolbar_title);

        listView = (ListView) findViewById(R.id.list);
        et_send_msg = (EditText) findViewById(R.id.send_msg);
        btn_send = (Button) findViewById(R.id.send);
        welcome = getResources().getStringArray(R.array.welcome);
        signup = findViewById(R.id.signup);

        signup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!GlobalData.getUsername().isEmpty()) {
                    setSignup();
                } else {
                    showLoginAlertDialog();
                }
            }
        });
        if (user.getObjectId() != null) {
            Log.e("objectId", user.toString());
            ChatHistory chatHistory = new ChatHistory();
            chatHistory.setUserId(user.getObjectId());
            NetworkUtils.getChatHistory(chatHistory, new BlinkCallback() {
                @Override
                public void onSuccess(ResultBody<?> response) {
                    if (response.getCode() == 200){
                        Log.e("UserWithChat", "获取到聊天记录");
                        BaseResponse<?> data = (BaseResponse<?>) response.getData();
                        List<?> data1 = (List<?>) data.getData();
                        if (data1.isEmpty()) {
                            showFirstMessage();
                            return;
                        }
                        for (Object object : data1) {
                            ChatHistory chatHistory = (ChatHistory) object;
                            ChatWithUser chatWithUser1 = new ChatWithUser();
                            chatWithUser1.setState(chatHistory.getState());
                            chatWithUser1.setMessage(chatHistory.getMessage());
                            chatBeanList.add(chatWithUser1);
                        }
                        adapter.notifyDataSetChanged();
                        showFirstMessage();
                        return;
                    }
                    Log.e("e", "getChatHistory");
                }

                @Override
                public void onFailure(Throwable throwable) {
                    Log.e("e", "网络异常");
                }
            });
        }else {
            position = (int) (Math.random() * welcome.length);
            Log.e("welcome[position]",welcome[position]);
            showData(welcome[position]);
        }

        if (chatBeanList == null) {
            chatBeanList = new ArrayList<>();
        }
        adapter = new ChatContentAdapter(this, chatBeanList,this);
        listView.setAdapter(adapter);
        btn_send.setOnClickListener(v -> sendData());
        et_send_msg.setOnKeyListener((v, keyCode, keyEvent) -> {
            if ((keyCode == KeyEvent.KEYCODE_ENTER) && (keyEvent.getAction() == KeyEvent.ACTION_DOWN)) {
                sendData();
            }
            return false;
        });

        FloatingActionButton floatingActionButton = findViewById(R.id.float_collection);
        floatingActionButton.setOnTouchListener(new View.OnTouchListener() {
            private float initialX, initialY;
            private float initialTouchX, initialTouchY;
            private final int screenWidth = getResources().getDisplayMetrics().widthPixels;

            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = view.getX();
                        initialY = view.getY();
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        float deltaX = event.getRawX() - initialTouchX;
                        float deltaY = event.getRawY() - initialTouchY;
                        float newX = initialX + deltaX;
                        float newY = initialY + deltaY;
                        newX = Math.max(0, Math.min(newX, screenWidth - view.getWidth()));
                        newY = Math.max(0, Math.min(newY, getResources().getDisplayMetrics().heightPixels - view.getHeight()));
                        view.setX(newX);
                        view.setY(newY);
                        return true;
                    case MotionEvent.ACTION_UP:
                        float center = screenWidth / 2f;
                        float finalX = view.getX() + view.getWidth() / 2f > center ? screenWidth - view.getWidth() : 0;
                        view.animate()
                                .x(finalX)
                                .setDuration(200)
                                .start();

                        if (Math.abs(event.getRawX() - initialTouchX) < 10 && Math.abs(event.getRawY() - initialTouchY) < 10) {
                            view.performClick();
                        }
                        return true;
                }
                return false;
            }

        });

        floatingActionButton.performClick();
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tips();
            }
        });

        navigationBarSpacer = findViewById(R.id.navigation_bar_spacer);

        setupKeyboardListener();
        setupNavigationBarSpacer();

        // 初始化版本管理器
        VersionManager versionManager = new VersionManager(this);
        // 应用启动后静默检查更新
        versionManager.checkUpdateSilently();
    }

    private void setupFullScreenDisplay() {
        // 设置状态栏透明，内容延伸到状态栏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            getWindow().setDecorFitsSystemWindows(false);
        } else {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            );
        }

        // 设置状态栏和导航栏颜色
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
    }

    private void setupNavigationBarSpacer() {
        // 动态设置导航栏空白区域高度
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.bottom_container),
                    (v, windowInsets) -> {
                        Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars());

                        // 设置底部间距以避免被导航栏遮挡
                        ViewGroup.LayoutParams params = navigationBarSpacer.getLayoutParams();
                        params.height = insets.bottom;
                        navigationBarSpacer.setLayoutParams(params);

                        return windowInsets;
                    });
        } else {
            // 兼容老版本Android
            findViewById(R.id.bottom_container).getViewTreeObserver().addOnGlobalLayoutListener(
                    new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            adjustForNavigationBar();
                        }
                    });
        }
    }

    private void adjustForNavigationBar() {
        // 获取导航栏高度
        int navigationBarHeight = getNavigationBarHeight();

        // 检查是否显示导航栏
        if (isNavigationBarShowing()) {
            ViewGroup.LayoutParams params = navigationBarSpacer.getLayoutParams();
            params.height = navigationBarHeight;
            navigationBarSpacer.setLayoutParams(params);
        } else {
            ViewGroup.LayoutParams params = navigationBarSpacer.getLayoutParams();
            params.height = 0;
            navigationBarSpacer.setLayoutParams(params);
        }
    }

    private int getNavigationBarHeight() {
        int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    private boolean isNavigationBarShowing() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Display display = getWindowManager().getDefaultDisplay();
            DisplayMetrics realDisplayMetrics = new DisplayMetrics();
            display.getRealMetrics(realDisplayMetrics);

            DisplayMetrics displayMetrics = new DisplayMetrics();
            display.getMetrics(displayMetrics);

            return realDisplayMetrics.heightPixels - displayMetrics.heightPixels > 0;
        }
        return false;
    }

    private void setupKeyboardListener() {
        // 监听软键盘弹出，自动滚动到底部
        findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        Rect r = new Rect();
                        findViewById(android.R.id.content).getWindowVisibleDisplayFrame(r);
                        int screenHeight = findViewById(android.R.id.content).getRootView().getHeight();
                        int keypadHeight = screenHeight - r.bottom;

                        if (keypadHeight > screenHeight * 0.15) {
                            // 键盘弹出，滚动到底部
                            scrollToBottom();
                        }
                    }
                });
    }

    private void scrollToBottom() {
        if (listView.getAdapter() != null && listView.getAdapter().getCount() > 0) {
            listView.post(() -> {
                listView.setSelection(listView.getAdapter().getCount() - 1);
            });
        }
    }

    private String getCurrentAppVersion() {
        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            return packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            return "-1"; // 返回-1表示获取版本号失败
        }
    }

    private boolean isEnglishLanguage() {
        Locale locale = getResources().getConfiguration().locale;
        String language = locale.getLanguage();
        return language.equals("en");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        return true;
    }

    private void showFirstMessage() {
        if (user.getObjectId() != null) {
            ChatHistory chatHistory = new ChatHistory(user.getObjectId(), welcome[position], ChatWithUser.RECEIVE);

            NetworkUtils.getChatHistory(chatHistory, new BlinkCallback() {
                @Override
                public void onSuccess(ResultBody<?> response) {
                    if (response.getCode() == 200){
                        BaseResponse<?> data = (BaseResponse<?>) response.getData();
                        List<?> data1 = (List<?>) data.getData();
                        if (data1.isEmpty()){
                            NetworkUtils.saveChatHistory(chatHistory, new BlinkCallback(){
                                @Override
                                public void onSuccess(ResultBody<?> response) {
                                    Log.e("saveChatHistory-response", response.toString());
                                }

                                @Override
                                public void onFailure(Throwable throwable) {
                                    Log.e("saveChatHistory-throwable", throwable.toString());
                                }
                            });
                        }else {
                            position = (int) (Math.random() * welcome.length);
                            showData(welcome[position]);
                            Log.e("getChatHistory2","notEmpty");
                        }

                    }else {
                        Log.e("showFirstMessage-response",response.toString());
                    }
                }

                @Override
                public void onFailure(Throwable throwable) {
                    Log.e("showFirstMessage-throwable",throwable.toString());
                }
            });

        }else {
            position = (int) (Math.random() * welcome.length);
            showData(welcome[position]);
        }
    }

    private void getDataFromServerForFree() {
        OkHttpClient okHttpClient = new OkHttpClient();

        try {
            String encodeMsg = URLEncoder.encode(send_Msg, "UTF-8");
            Request request;
            if (user == null){
                request = new Request.Builder()
                        .url(BaseURL.FREE + "?appid=" + BaseURL.KEY + "&userid=" + UUID.randomUUID().toString() + "&spoken=" + encodeMsg)
                        .build();
            }else {
                request = new Request.Builder()
                        .url(BaseURL.FREE + "?appid=" + BaseURL.KEY + "&userid=" + user.getLoginId() + "&spoken=" + encodeMsg)
                        .build();
            }
            Call call = okHttpClient.newCall(request);

            call.enqueue(new Callback() {
                @Override
                public void onFailure(@NonNull Call call, @NonNull IOException e) {
                    Log.e("e", e.toString());
                    handler.post(() -> {
                        btn_send.setEnabled(true);
                        btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                        showCenteredToast(getString(R.string.Master_I_have_a_fault_please_try_again_later));
                    });
                }

                @Override
                public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                    String res = response.body() != null ? response.body().string() : null;
                    Message msg = new Message();
                    msg.what = MSG_OK;
                    msg.obj = res;
                    Log.e("res", res);
                    handler.sendMessage(msg);
                }
            });
        } catch (Exception e) {
            handler.post(() -> {
                btn_send.setEnabled(true);
                btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                showCenteredToast(getString(R.string.Master_I_have_a_fault_please_try_again_later));
            });
            Log.e("e", e.toString());
        }
    }

    @SuppressLint("HandlerLeak")
    private final Handler handler = new Handler() {
        @Override
        public void dispatchMessage(@NonNull Message msg) {
            super.dispatchMessage(msg);
            if (msg.what == 1) {
                if (msg.obj != null) {
                    String result = (String) msg.obj;
                    Log.i("handler", result);
                    paresData(result);
                }
            }
        }
    };

    private void paresData(String content) {
        try {
            JSONObject jsonObject = new JSONObject(content);
            JSONObject data = jsonObject.getJSONObject("data");
            int code = jsonObject.getInt("status");
            String resContent = data.getJSONObject("info").getString("text");
            resContent = resContent.replace("{br}", "\n");
            String type = data.getString("type");
            Log.i("paresData", resContent + "," + code+"," + type);
            updateView(code, resContent);
            btn_send.setEnabled(true);
            btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
            if (user.getObjectId() != null) {
                ChatHistory chatHistory = new ChatHistory();
                chatHistory.setUserId(user.getObjectId());
                chatHistory.setMessage(resContent);
                chatHistory.setState(ChatWithUser.RECEIVE);
                NetworkUtils.saveChatHistory(chatHistory, new BlinkCallback() {
                    @Override
                    public void onSuccess(ResultBody<?> response) {
                        Log.e("saveChatHistory-paresData-response", response.toString());
                    }

                    @Override
                    public void onFailure(Throwable throwable) {
                        Log.e("saveChatHistory-paresData-throwable", throwable.toString());
                    }
                });
            }
        } catch (JSONException e) {
            handler.post(() -> {
                btn_send.setEnabled(true);
                btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                showCenteredToast(getString(R.string.Master_I_have_a_fault_please_try_again_later));
            });
            Log.e("e", e.toString());
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                if (currentToast != null) {
                    currentToast.cancel();
                }

                currentToast = Toast.makeText(AI.this, R.string.Press_again_to_exit_the_program, Toast.LENGTH_SHORT);
                currentToast.show();

                exitTime = System.currentTimeMillis();
            } else {
                AppsManager.finishAll();
                System.exit(0);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);

    }

    private void getDataFromServerForLoginUser() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Handler handler = new Handler(Looper.getMainLooper());

        try {
            send_Msg = URLEncoder.encode(send_Msg, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        executor.execute(() -> {
            OkHttpClient client = new OkHttpClient();
            MediaType mediaType = MediaType.parse(BaseURL.CONTENT_TYPE);
            RequestBody body = RequestBody.create(mediaType, "{\n\"model\": \"gpt-3.5-turbo\",\n\"messages\": [{\"role\": \"user\", \"content\": \"" + send_Msg + "\"}],\n\"temperature\": 0.7\n}");
            Request request = new Request.Builder()
                    .url(BaseURL.LOGIN)
                    .post(body)
                    .addHeader("Content-Type", BaseURL.CONTENT_TYPE)
                    .addHeader("Authorization", BaseURL.AUTHORIZATION)
                    .build();

            try {
                try (Response response = client.newCall(request).execute()) {
                    String responseBody = Objects.requireNonNull(response.body()).string();
                    Log.i("responseBody", responseBody);

                    handler.post(() -> {
                        try {
                            JSONObject jsonObject = new JSONObject(responseBody);
                            Log.i("jsonObject", jsonObject.toString());
                            JSONArray choicesArray = jsonObject.getJSONArray("choices");
                            for (int i = 0; i < choicesArray.length(); i++) {
                                JSONObject choice = choicesArray.getJSONObject(i);
                                JSONObject messageObject = choice.getJSONObject("message");
                                String content = messageObject.getString("content");
                                Log.i("content", content);
                                updateView(1, content);
                                btn_send.setEnabled(true);
                                btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                                if (user.getObjectId() != null) {
                                    ChatHistory chatHistory = new ChatHistory();
                                    chatHistory.setUserId(user.getObjectId());
                                    chatHistory.setMessage(content);
                                    chatHistory.setState(ChatWithUser.RECEIVE);
                                    NetworkUtils.saveChatHistory(chatHistory, new BlinkCallback() {
                                        @Override
                                        public void onSuccess(ResultBody<?> response) {
                                            Log.e("saveChatHistory-getDataFromServerForLoginUser-response", response.toString());
                                        }

                                        @Override
                                        public void onFailure(Throwable throwable) {
                                            Log.e("saveChatHistory-getDataFromServerForLoginUser-throwable", throwable.toString());
                                        }
                                    });
                                }
                            }
                        } catch (JSONException e) {
                            handler.post(() -> {
                                btn_send.setEnabled(true);
                                btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                                showCenteredToast(getString(R.string.Master_I_have_a_fault_please_try_again_later));
                            });
                            Log.e("e", e.toString());
                        }
                    });

                    if (!response.isSuccessful()) {
                        handler.post(() -> {
                            btn_send.setEnabled(true);
                            btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                            showData(getString(R.string.Master_I_have_a_fault_please_try_again_later));
                        });
                        throw new IOException("Unexpected code " + response);
                    }
                }
            } catch (IOException e) {
                handler.post(() -> {
                    btn_send.setEnabled(true);
                    btn_send.setBackgroundResource(R.drawable.ic_send_pressed);
                    showCenteredToast(getString(R.string.Master_I_have_a_fault_please_try_again_later));
                });
                Log.e("e", e.toString());
            }
        });
    }

    private void updateView(int code, String content) {
        switch (code) {
            case 4094:
                showData(getString(R.string.Master1));
                break;
            case 40005:
                showData(getString(R.string.Master2));
                break;
            case 40886:
                showData(getString(R.string.Master3));
                break;
            case 40807:
                showData(getString(R.string.Master4));
                break;
            case 102:
                showData(getString(R.string.Master5));
                break;
            default:
                showData(content);
                break;
        }
    }

    private void showData(String message) {
        ChatWithUser chatBean = new ChatWithUser();
        chatBean.setMessage(message);
        chatBean.setState(ChatWithUser.RECEIVE);
        Log.e("chatBean",chatBean.toString());
        chatBeanList.add(chatBean);
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        } else {
            adapter = new ChatContentAdapter(this, chatBeanList,this);
            listView.setAdapter(adapter);
        }

    }

    private void sendData() {
        send_Msg = et_send_msg.getText().toString();
        if (TextUtils.isEmpty(send_Msg)) {
            if (currentToast != null) {
                currentToast.cancel();
            }

            currentToast = Toast.makeText(this, R.string.You_havent_entered_any_information_yet, Toast.LENGTH_SHORT);
            currentToast.show();

            return;
        }

        if (!btn_send.isEnabled()) {
            showCenteredToast(getString(R.string.Please_try_again_later));
            return;
        }

        btn_send.setEnabled(false);
        btn_send.setBackgroundResource(R.drawable.ic_send);
        et_send_msg.setText("");

        chatWithUser = new ChatWithUser();
        chatWithUser.setMessage(send_Msg);
        chatWithUser.setState(ChatWithUser.SEND);
        chatBeanList.add(chatWithUser);
        adapter.notifyDataSetChanged();
        if (user.getObjectId() != null) {
            ChatHistory chatHistory = new ChatHistory();
            chatHistory.setUserId(user.getObjectId());
            chatHistory.setMessage(send_Msg);
            chatHistory.setState(ChatWithUser.SEND);
            NetworkUtils.saveChatHistory(chatHistory, new BlinkCallback() {
                @Override
                public void onSuccess(ResultBody<?> response) {
                    Log.e("saveChatHistory-sendData-response", response.toString());
                }

                @Override
                public void onFailure(Throwable throwable) {
                    Log.e("saveChatHistory-sendData-throwable", throwable.toString());
                }
            });

            UserQuery userQuery = new UserQuery();
            userQuery.setUserId(user.getObjectId());
            userQuery.setQueries(send_Msg);
            userQuery.setDate(getCurrentDate());
            NetworkUtils.saveUserQuery(userQuery, new BlinkCallback(){
                @Override
                public void onSuccess(ResultBody<?> response) {
                    Log.e("saveUserQuery-sendData-response", response.toString());
                }

                @Override
                public void onFailure(Throwable throwable) {
                    Log.e("saveUserQuery-sendData-throwable", throwable.toString());
                }
            });
        }

        UserWithChat userWithChat = new UserWithChat();
        userWithChat.setName(GlobalData.getUsername());
        NetworkUtils.getUserWithChatByName(userWithChat, new BlinkCallback() {
            @Override
            public void onSuccess(ResultBody<?> response) {
                if (response.getCode() == 200 ){
                    CommonResponse data = (CommonResponse) response.getData();
                    checkAndUpdateCount(data.getSuccess());
                    return;
                }
                Log.e("getUserWithChatByName-response", response.toString());
            }

            @Override
            public void onFailure(Throwable throwable) {
                Log.e("getUserWithChatByName-throwable", throwable.toString());
            }
        });
    }

    private void checkAndUpdateCount(boolean isLoginUser) {
        SharedPreferences prefs = getSharedPreferences(BaseURL.PREFS_NAME, MODE_PRIVATE);
        String savedDate = prefs.getString(BaseURL.PREFS_DATE, "");
        String currentDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());

        int countFree = prefs.getInt(BaseURL.PREFS_COUNT_FREE, 0);
        int countLogin = prefs.getInt(BaseURL.PREFS_COUNT_LOGIN, 0);

        if (!currentDate.equals(savedDate)) {

            countFree = 0;
            countLogin = 0;
            prefs.edit().putString(BaseURL.PREFS_DATE, currentDate).apply();
        }

        if (isLoginUser) {
            if (countLogin >= 50) {

                showLimitReachedDialog(true);
                return;
            }
            prefs.edit().putInt(BaseURL.PREFS_COUNT_LOGIN, countLogin + 1).apply();
            getDataFromServerForLoginUser();
        } else {
            if (countFree >= 10) {

                showLimitReachedDialog(false);
                return;
            }
            prefs.edit().putInt(BaseURL.PREFS_COUNT_FREE, countFree + 1).apply();
            getDataFromServerForFree();
        }
    }

    private void showLimitReachedDialog(boolean isRegisteredUser) {
        mUserEarnedReward = false;
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.Limit_Reached);

        if (isRegisteredUser) {
            builder.setMessage(R.string.tomorrow);
        } else {
            builder.setMessage(R.string.Please_register_to_continue_using_the_service);
        }

        builder.setPositiveButton(R.string.Get_for_free, (dialog, which) -> {
            dialog.dismiss();
            showRewardedAd(isRegisteredUser);
            Map<String, Object> eventValues = new HashMap<String, Object>();
            if (isRegisteredUser) {
                eventValues.put("login-user-ads", "showRewardedAd");
                eventValues.put("login-user-account", GlobalData.getUsername());
                AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                        "login-user-rewarded", eventValues,new AppsFlyerRequestListener() {
                            @Override
                            public void onSuccess() {
                                Log.d(TAG, "Event sent successfully");
                            }
                            @Override
                            public void onError(int i, @NonNull String s) {
                                Log.d(TAG, "Event failed to be sent:\n" +
                                        "Error code: " + i + "\n"
                                        + "Error description: " + s);
                            }
                        });
            } else {
                eventValues.put("free-user-ads", "showRewardedAd");
                AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                        "free-user-rewarded", eventValues,new AppsFlyerRequestListener() {
                            @Override
                            public void onSuccess() {
                                Log.d(TAG, "Event sent successfully");
                            }
                            @Override
                            public void onError(int i, @NonNull String s) {
                                Log.d(TAG, "Event failed to be sent:\n" +
                                        "Error code: " + i + "\n"
                                        + "Error description: " + s);
                            }
                        });
            }
        });


        if (!isRegisteredUser) {
            builder.setNegativeButton(R.string.Register, (dialog, which) -> {

                Intent intent = new Intent(this, Register.class);
                startActivity(intent);
            });
        }

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    private void showRewardedAd(boolean isRegisteredUser) {
        if (mRewardedAd != null) {
            mRewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
                @Override
                public void onAdShowedFullScreenContent() {
                    // 当广告显示时触发
                    Toast.makeText(AI.this, R.string.Ads_Tips, Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onAdFailedToShowFullScreenContent(AdError adError) {
                    // 当广告展示失败时触发
                    mRewardedAd = null;
                }

                @Override
                public void onAdDismissedFullScreenContent() {
                    // 当广告被关闭时触发
                    if (mUserEarnedReward) {
                        // 用户观看广告并获得奖励
                        Log.d("AdMob", "用户获得了奖励！");
                        SharedPreferences prefs = getSharedPreferences(BaseURL.PREFS_NAME, MODE_PRIVATE);
                        int countFree = 0;
                        int countLogin = 40;
                        if (isRegisteredUser){
                            prefs.edit().putInt(BaseURL.PREFS_COUNT_LOGIN, countLogin).apply();
                            getDataFromServerForLoginUser();
                        }else {
                            prefs.edit().putInt(BaseURL.PREFS_COUNT_FREE, countFree).apply();
                            getDataFromServerForFree();
                        }
                        Toast.makeText(AI.this, R.string.Gift, Toast.LENGTH_SHORT).show();
                    } else {
                        // 用户中途关闭广告，没有获得奖励
                        Toast.makeText(AI.this, R.string.Not_Gift, Toast.LENGTH_SHORT).show();
                        Log.d("AdMob", "用户未获得奖励，因为广告未完整观看。");
                    }
                    // 重新加载广告
                    loadRewardedAd();
                }
            });

            mRewardedAd.show(AI.this, new OnUserEarnedRewardListener() {
                @Override
                public void onUserEarnedReward(RewardItem rewardItem) {
                    // 当用户完整观看广告时触发
                    mUserEarnedReward = true; // 标记用户已获得奖励
                    Map<String, Object> eventValues = new HashMap<String, Object>();
                    if (isRegisteredUser){
                        eventValues.put("login-user-earned-reward", "EarnedReward");
                        AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                "login-user-earned-reward", eventValues,new AppsFlyerRequestListener() {
                                    @Override
                                    public void onSuccess() {
                                        Log.d(TAG, "Event sent successfully");
                                    }
                                    @Override
                                    public void onError(int i, @NonNull String s) {
                                        Log.d(TAG, "Event failed to be sent:\n" +
                                                "Error code: " + i + "\n"
                                                + "Error description: " + s);
                                    }
                                });
                    }else {
                        eventValues.put("free-user-earned-reward", "EarnedReward");
                        AppsFlyerLib.getInstance().logEvent(getApplicationContext(),
                                "free-user-earned-reward", eventValues,new AppsFlyerRequestListener() {
                                    @Override
                                    public void onSuccess() {
                                        Log.d(TAG, "Event sent successfully");
                                    }
                                    @Override
                                    public void onError(int i, @NonNull String s) {
                                        Log.d(TAG, "Event failed to be sent:\n" +
                                                "Error code: " + i + "\n"
                                                + "Error description: " + s);
                                    }
                                });
                    }
                }
            });
        } else {
            Toast.makeText(AI.this, R.string.No_Ads, Toast.LENGTH_SHORT).show();
            Log.d("AdMob", "广告尚未加载");
        }
    }

    private void loadRewardedAd() {
        AdRequest adRequest = new AdRequest.Builder().build();

        RewardedAd.load(this, BaseURL.AD_UNIT_ID, adRequest, new RewardedAdLoadCallback() {
            @Override
            public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                super.onAdFailedToLoad(loadAdError);
                mRewardedAd = null;
            }

            @Override
            public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
                super.onAdLoaded(rewardedAd);
                mRewardedAd = rewardedAd;
                String userId;
                if (GlobalData.getUsername().isEmpty()){
                    userId = UUID.randomUUID().toString();
                }else {
                    userId = GlobalData.getUser().getObjectId();
                }
                rewardedAd.setServerSideVerificationOptions(
                        new ServerSideVerificationOptions.Builder()
                                .setUserId(userId) // 用户ID
                                .build()
                );
            }
        });
    }

    private String getCurrentDate() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        return dateFormat.format(new Date());
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (Flash.isFlag()) {
            chatBeanList.clear();
            adapter.notifyDataSetChanged();
            Log.e("eeee", "我刷新了");
            showFirstMessage();
            Flash.setFlag(false);
        }
    }

    private void showCenteredToast(String message) {
        if (currentToast != null) {
            currentToast.cancel();
        }

        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.customize_toast,
                findViewById(R.id.custom_toast_container));

        TextView text = layout.findViewById(R.id.text);
        text.setText(message);

        currentToast = new Toast(getApplicationContext());
        currentToast.setGravity(Gravity.CENTER, 0, 0);
        currentToast.setDuration(Toast.LENGTH_SHORT);
        currentToast.setView(layout);
        currentToast.show();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.action_settings) {

            Intent intent = new Intent(this, Settings.class);
            startActivity(intent);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private boolean isValidSignUpTime() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            String lastSignUpDate = GlobalData.getSignup().getLastSignUpDate();
            if (lastSignUpDate == null || lastSignUpDate.isEmpty()) {
                return true;
            }
            Date last = sdf.parse(lastSignUpDate);
            Date now = new Date();
            return last == null || !sdf.format(last).equals(sdf.format(now));
        } catch (Exception e) {
            Log.e("SignUp", "Error validating sign up time", e);
            return false;
        }
    }

    public void setSignup() {
        if (isSigningUp) {
            if (currentToast != null) {
                currentToast.cancel();
            }

            currentToast = Toast.makeText(this, R.string.You_have_already_signed_up_today, Toast.LENGTH_SHORT);
            currentToast.show();
            return;
        }

        if (!isValidSignUpTime()){
            if (currentToast != null) {
                currentToast.cancel();
            }

            currentToast = Toast.makeText(this, R.string.come_back_tomorrow, Toast.LENGTH_SHORT);
            currentToast.show();
            return;
        }

        isSigningUp = true;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
        String today = sdf.format(new Date());

        String lastSignUpDate = GlobalData.getSignup().getLastSignUpDate() == null ? "" : GlobalData.getSignup().getLastSignUpDate();

        if (!today.equals(lastSignUpDate)) {
            SignUp signUp = new SignUp();
            signUp.setUserId(GlobalData.objectId);
            signUp.setLastSignUpDate(today);

            NetworkUtils.signUp(signUp, new BlinkCallback() {
                @Override
                public void onSuccess(ResultBody<?> response) {
                    isSigningUp = false;
                    runOnUiThread(() -> {
                        try {
                            if (response.getCode() == 200) {
                                Log.e("signUp-response", response.toString());
                                CommonResponse data = (CommonResponse) response.getData();
                                if (data.getSuccess()) {
                                    // 更新本地签到数据
                                    SignUp currentSignUp = GlobalData.getSignup();
                                    currentSignUp.setLastSignUpDate(today);
                                    GlobalData.setSignup(currentSignUp);

                                    // 显示签到成功对话框
                                    write = new AlertDialog.Builder(AI.this).create();
                                    sigup_view = LayoutInflater.from(AI.this).inflate(R.layout.signup, null);
                                    write.setView(sigup_view);
                                    write.show();

                                    // 可选：保存到 SharedPreferences 以确保数据持久化
                                    saveSignUpDateToPreferences(today);
                                } else {
                                    Toast.makeText(AI.this, R.string.Network_error, Toast.LENGTH_SHORT).show();
                                }
                            } else {
                                Toast.makeText(AI.this, R.string.Network_error, Toast.LENGTH_SHORT).show();
                            }
                        } catch (Exception e) {
                            Log.e("SignUp", "Error processing sign up response", e);
                            Toast.makeText(AI.this, R.string.Network_error, Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onFailure(Throwable throwable) {
                    isSigningUp = false;
                    runOnUiThread(() -> {
                        Toast.makeText(AI.this, R.string.Network_error, Toast.LENGTH_SHORT).show();
                    });
                }
            });
        } else {
            Toast.makeText(this, R.string.You_have_already_signed_up_today, Toast.LENGTH_SHORT).show();
        }
    }

    // 添加持久化存储方法
    private void saveSignUpDateToPreferences(String date) {
        SharedPreferences prefs = getSharedPreferences("SignUpData", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString("lastSignUpDate", date);
        editor.apply();
    }

    private void syncSignUpData() {
        // 获取服务器端的签到数据
        if (GlobalData.objectId != null) {
            NetworkUtils.getByUserId(GlobalData.objectId, new BlinkCallback() {
                @Override
                public void onSuccess(ResultBody<?> response) {
                    if (response.getCode() == 200) {
                        BaseResponse<?> data1 = (BaseResponse<?>) response.getData();
                        SignUp data2 = (SignUp) data1.getData();
                        if (data2 != null) {
                            GlobalData.setSignup(data2);
                        }
                    }
                }

                @Override
                public void onFailure(Throwable throwable) {
                    Log.e("SignUp", "Error syncing sign up data", throwable);
                }
            });
        }
    }

    public void tips() {

        write = new AlertDialog.Builder(this).create();
        comparision_view = LayoutInflater.from(this).inflate(R.layout.comparison, null);
        write.setView(comparision_view);
        write.show();
    }

    private void showLoginAlertDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.login_is_required)
                .setMessage(R.string.login_is_required_message)
                .setPositiveButton(R.string.login, (dialog, which) -> {
                    dialog.dismiss();
                    Intent intent = new Intent(this, Login.class);
                    startActivity(intent);
                }).setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()).setCancelable(false).setCancelable(false)
                .show();
    }

    @Override
    public void onMessageLongClick(ChatWithUser message) {
        showReportDialog(message);
    }

    private void showReportDialog(ChatWithUser message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        LayoutInflater inflater = this.getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.report_dialog, null);
        builder.setView(dialogView);

        Spinner spinnerReportType = dialogView.findViewById(R.id.spinner_report_type);
        EditText edittextReportDescription = dialogView.findViewById(R.id.edittext_report_description);

        // Populate the spinner with report types
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.report_types, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerReportType.setAdapter(adapter);

        builder.setTitle(R.string.report_message)
                .setPositiveButton(R.string.report, (dialog, which) -> {
                    String reportType = spinnerReportType.getSelectedItem().toString();
                    String reportDescription = edittextReportDescription.getText().toString();
                    handleReportMessage(message, reportType, reportDescription);
                })
                .setNegativeButton(R.string.cancel_report, (dialog, which) -> dialog.dismiss())
                .create()
                .show();
    }

    private void handleReportMessage(ChatWithUser message, String reportType, String reportDescription) {
        // Handle the report, e.g., send to server or save locally
        NetworkUtils.postReport(message.getMessage(), reportType, reportDescription, new NetworkCallback() {
            @Override
            public void onSuccess(ReturnedValue response) {
                Toast.makeText(AI.this, R.string.message_reported, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Throwable throwable) {
                Toast.makeText(AI.this, R.string.message_reported_failed, Toast.LENGTH_SHORT).show();
            }
        });
    }

}
